#ifndef SSDB_ITERATOR_H_
#define SSDB_ITERATOR_H_

#include "bytes.h"
#include <inttypes.h>
#include <string>
#include <memory>

namespace leveldb {
class Iterator;
}

namespace ssdb {

class Iterator {
public:
  enum Direction { FORWARD, BACKWARD };
  Iterator(std::shared_ptr<leveldb::Iterator> it, const std::string &end, uint64_t limit,
           Direction direction = Iterator::FORWARD);
  ~Iterator();
  bool skip(uint64_t offset);
  bool next();
  Bytes key();
  Bytes val();

private:
  std::shared_ptr<leveldb::Iterator> it;
  std::string end;
  uint64_t limit;
  bool is_first;
  int direction;
};

class KIterator {
public:
  std::string key;
  std::string val;

  KIterator(std::shared_ptr<Iterator> it);
  ~KIterator();
  void return_val(bool onoff);
  bool next();

private:
  std::shared_ptr<Iterator> it;
  bool return_val_;
};

class HIterator {
public:
  std::string name;
  std::string key;
  std::string val;

  HIterator(std::shared_ptr<Iterator> it, const Bytes &name);
  ~HIterator();
  void return_val(bool onoff);
  bool next();

private:
  std::shared_ptr<Iterator> it;
  bool return_val_;
};

class ZIterator {
public:
  std::string name;
  std::string key;
  std::string score;

  ZIterator(std::shared_ptr<Iterator> it, const Bytes &name);
  ~ZIterator();
  bool skip(uint64_t offset);
  bool next();

private:
  std::shared_ptr<Iterator> it;
};

}

#endif
